package com.jzr.medical.db1.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jzr.common.util.U;
import com.jzr.medical.common.LayServiceImpl;
import com.jzr.medical.common.SecurityHelper;
import com.jzr.medical.db1.mapper.TRoleDeptRefMapper;
import com.jzr.medical.db1.mapper.TRoleMapper;
import com.jzr.medical.db1.mapper.TRoleMenuRefMapper;
import com.jzr.medical.db1.mapper.TUserRoleRefMapper;
import com.jzr.medical.db1.model.TRole;
import com.jzr.medical.db1.model.TRoleDeptRef;
import com.jzr.medical.db1.model.TRoleMenuRef;
import com.jzr.medical.db1.model.TUserRoleRef;
import com.jzr.medical.db1.service.RoleService;
import com.jzr.medical.db1.vo.RoleDeptVo;
import com.jzr.medical.db1.vo.RoleMenuTreeVo;
import com.jzr.medical.db1.vo.RoleUserVo;
import com.jzr.medical.db1.vo.RoleVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

@Service
public class RoleServiceImpl extends LayServiceImpl<TRoleMapper,TRole,RoleVo,Integer> implements RoleService {
    @Autowired
    private TRoleMenuRefMapper tRoleMenuRefMapper;

    @Autowired
    private TUserRoleRefMapper tUserRoleRefMapper;

    @Autowired
    private TRoleDeptRefMapper tRoleDeptRefMapper;


    @Override
    public List<Map<String, Object>> codeList() {
        return baseMapper.codeList();
    }

    @Override
    public boolean isHasMenu(Integer id) {
        QueryWrapper<TRoleMenuRef> qw = new QueryWrapper<>();
        qw.eq(TRoleMenuRef.RoleId_,id);
        Integer count = tRoleMenuRefMapper.selectCount(qw);
        return count != null && count.intValue()>0;
    }

    @Override
    public boolean isHasUser(Integer id) {
        QueryWrapper<TUserRoleRef> qw = new QueryWrapper<>();
        qw.eq(TUserRoleRef.RoleId_,id);
        Integer count = tUserRoleRefMapper.selectCount(qw);
        return count != null && count.intValue()>0;
    }

    @Override
    public List<RoleMenuTreeVo> getRoleMenuTree(Integer roleId) {
        return baseMapper.getRoleMenuTree(roleId);
    }

    private void deleteRoleMenuNotSelected(Integer roleId, List<Integer> menuIds){
        QueryWrapper<TRoleMenuRef> qw = new QueryWrapper<>();
        qw.eq(TRoleMenuRef.RoleId_,roleId)
                .notIn(TRoleMenuRef.MenuId_,menuIds);
        tRoleMenuRefMapper.delete(qw);
    }

    private void insertRoleMenuNotExists(Integer roleId, List<Integer> menuIds){
        Integer userId = SecurityHelper.getUserId();

        for(Integer menuId : menuIds){
            Integer count = tRoleMenuRefMapper.selectCount(new QueryWrapper<TRoleMenuRef>()
                    .eq(TRoleMenuRef.RoleId_,roleId)
                    .eq(TRoleMenuRef.MenuId_,menuId)
            );
            if(count==null || count.intValue()<=0){
                TRoleMenuRef tRoleMenuRef = new TRoleMenuRef();
                tRoleMenuRef.setRoleId(roleId);
                tRoleMenuRef.setMenuId(menuId);
                tRoleMenuRef.setUpdateBy(userId);
                tRoleMenuRef.setUpdateTime(LocalDateTime.now());
                tRoleMenuRefMapper.insert(tRoleMenuRef);
            }
        }
    }
    @Override
    public Integer saveRoleMenuTree(Integer roleId,List<Integer> menuIds){
        if(U.isBlank(roleId)){
            return 0;
        }
        if(U.isBlank(menuIds) || menuIds.size() <= 0){
            return 0;
        }

        deleteRoleMenuNotSelected(roleId,menuIds);

        insertRoleMenuNotExists(roleId,menuIds);

        return 1;
    }

    @Override
    public List<RoleUserVo> getUserList(Integer roleId) {
        return baseMapper.getUserList(roleId);
    }

    private void deleteRoleUserNotSelected(Integer roleId, List<Integer> userIds){
        tUserRoleRefMapper.delete(new QueryWrapper<TUserRoleRef>()
                .eq(TUserRoleRef.RoleId_,roleId)
                .notIn(TUserRoleRef.UserId_,userIds)
        );
    }

    private void insertRoleUserNotExists(Integer roleId, List<Integer> userIds){
        Integer updateBy = SecurityHelper.getUserId();

        for(Integer userId : userIds){
            Integer count = tUserRoleRefMapper.selectCount(new QueryWrapper<TUserRoleRef>()
                    .eq(TUserRoleRef.RoleId_,roleId)
                    .eq(TUserRoleRef.UserId_,userId)
            );
            if(count == null || count.intValue()<=0){
                TUserRoleRef tUserRoleRef = new TUserRoleRef();
                tUserRoleRef.setRoleId(roleId);
                tUserRoleRef.setUserId(userId);
                tUserRoleRef.setUpdateBy(updateBy);
                tUserRoleRef.setUpdateTime(LocalDateTime.now());
                tUserRoleRefMapper.insert(tUserRoleRef);
            }
        }
    }

    @Override
    public Integer saveUserList(Integer roleId, List<Integer> userIds) {
        if(U.isBlank(roleId)){
            return 0;
        }
        if(U.isBlank(userIds) || userIds.size() <= 0){
            return 0;
        }

        deleteRoleUserNotSelected(roleId,userIds);

        insertRoleUserNotExists(roleId,userIds);

        return 1;
    }

    @Override
    public List<RoleDeptVo> getDeptList(Integer roleId) {
        return baseMapper.getDeptList(roleId);
    }

    private void deleteRoleDeptNotSelected(Integer roleId, List<Integer> deptIds){
        tRoleDeptRefMapper.delete(new QueryWrapper<TRoleDeptRef>()
                .eq(TRoleDeptRef.RoleId_,roleId)
                .notIn(TRoleDeptRef.DeptId_,deptIds)
        );
    }

    private void insertRoleDeptNotExists(Integer roleId, List<Integer> deptIds){
        Integer updateBy = SecurityHelper.getUserId();

        for(Integer deptId : deptIds){
            Integer count = tRoleDeptRefMapper.selectCount(new QueryWrapper<TRoleDeptRef>()
                    .eq(TRoleDeptRef.RoleId_,roleId)
                    .eq(TRoleDeptRef.DeptId_,deptId)
            );
            if(count == null || count.intValue()<=0){
                TRoleDeptRef tRoleDeptRef = new TRoleDeptRef();
                tRoleDeptRef.setRoleId(roleId);
                tRoleDeptRef.setDeptId(deptId);
                tRoleDeptRef.setUpdateBy(updateBy);
                tRoleDeptRef.setUpdateTime(LocalDateTime.now());
                tRoleDeptRefMapper.insert(tRoleDeptRef);
            }
        }
    }

    @Override
    public Integer saveDeptList(Integer roleId, List<Integer> deptIds) {
        if(U.isBlank(roleId)){
            return 0;
        }
        if(U.isBlank(deptIds) || deptIds.size() <= 0){
            return 0;
        }

        deleteRoleDeptNotSelected(roleId,deptIds);

        insertRoleDeptNotExists(roleId,deptIds);

        return 1;
    }
}
